package com.parking.user.controller;


import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.parking.common.core.model.Result;
import com.parking.common.core.model.StateData;
import com.parking.common.core.util.JwtUtil;
import com.parking.common.web.aop.Permission;
import com.parking.common.web.util.RedisUtil;
import com.parking.dto.UserAccountDto;
import com.parking.dto.UserDto;
import com.parking.dto.UserInfoDto;
import com.parking.dto.UserPhoneForm;
import com.parking.exception.UserException;
import com.parking.exception.UserExceptionCode;
import com.parking.form.AddUserForm;
import com.parking.form.PhongForm;
import com.parking.form.UserLoginForm;
import com.parking.user.entity.UserAccount;
import com.parking.user.entity.UserCar;
import com.parking.user.entity.UserInfo;
import com.parking.user.service.UserAccountService;
import com.parking.user.service.UserInfoService;
import io.jsonwebtoken.Claims;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ResponseHeader;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import javax.validation.constraints.Pattern;
import javax.validation.constraints.Size;
import java.util.HashMap;
import java.util.List;

/**
 * <p>
 *  前端控制器
 * </p>
 *
 * @author 香菜狗带
 * @since 2023年11月28日
 */
@RestController
@RequestMapping("/userAccount")
@Api(tags = "用户登录接口")
public class UserAccountController {
    @Resource
    private UserAccountService userAccountService;
    @Resource
    private UserInfoService userInfoService;
    @Resource
    private RedisUtil redisUtil;

    /***
     * 登录方法
     * 参数：
     * ("用户账号"): userAccount;
     * ("用户密码"): userPass;
     * ("请求头"): response
     */
    @PostMapping("/userLogin")
    @ApiOperation("用户登录")
    public Result userLogin(@RequestBody UserLoginForm form, HttpServletResponse response){
        UserInfoDto user=userAccountService.userLogin(form,response);
        //将用户信息存进Token
        String refreshToken = JwtUtil.createUserToken(3 * 24 * 60,"userId",user.getUserAccountId());
        String accessToken = JwtUtil.createUserToken(30,"userId",user.getUserAccountId());
        response.setHeader("authorization", accessToken);
        redisUtil.set(accessToken,refreshToken,3*24*60*60L);
        response.setHeader("Access-Control-Expose-Headers", "authorization");
        return Result.getResult(UserInfoDto.class).setCode(200).setMessage("登录成功").setData(user);
    }
    /***
     * 退出登录方法
     * 参数：
     ("用户Id")：userId;
     */
    @GetMapping("/LogOff.user")
    @ApiOperation("用户退出登录")
    public Result LogOff(String userAccount) throws Exception {
//        Integer userId = JwtUtil.getUserId(authorization);
        userAccountService.LogOff(userAccount);
        return Result.getResult().setMessage("退出登录成功").setCode(200);
    }
    /***
     * 用户注册验证码
     * 参数：
     * ("用户电话")：phone;
     */
    @PostMapping({"/sendRegisterCode"})
    @ApiOperation("用户注册发送验证码")
    public Result sendRegisterCode(@RequestBody @Valid PhongForm form) throws Exception {
        userAccountService.sendRegisterCode(form.getPhone());
        return Result.getResult().setMessage("发送短信成功").setCode(200);
    }
    /***
     * 用户注册
     * 参数：
     * ("用户账号")：userAccount;
     * ("用户密码")：userPass;
     * ("用户名称")：userInfoName;
     * ("用户电话")：userInfoTel;
     * ("用户身份证号")：userInfoCard;
     */
    @PostMapping("/addUserAccount")
    @ApiOperation("用户注册")
    public Result addUserAccount(@RequestBody @Valid AddUserForm form){
        userAccountService.addUserAccount(form);
        return Result.getResult().setMessage("用户注册成功").setCode(200);
    }
    /***
     * 用户登录验证码
     * 参数：
     * ("用户电话")：userInfoTel;
     */
    @PostMapping({"/sendLoginCode"})
    @ApiOperation("用户登录验证码")
    public Result sendLoginCode(@RequestBody @Valid PhongForm form) throws Exception {
        userAccountService.sendLoginCode(form.getPhone());
        return Result.getResult().setMessage("发送登录短信成功").setCode(200);
    }
    /***
     * 用户验证码登录
     * 参数：
     ("验证码")：code;
     ("用户手机号")：userInfoTel;
     */
    @PostMapping("/codeLogin")
    @ApiOperation("验证码登录接口")
    public Result codeLogin(@RequestBody @Valid UserPhoneForm form, HttpServletResponse response) throws Exception {
        UserInfoDto user=userAccountService.codeLogin(form);
        String refreshToken = JwtUtil.createUserToken(3 * 24 * 60,"userId",user.getUserAccountId());
        String accessToken = JwtUtil.createUserToken(30,"userId",user.getUserAccountId());
        response.setHeader("authorization", accessToken);
        redisUtil.set(accessToken,refreshToken,3*24*60*60L);
        response.setHeader("Access-Control-Expose-Headers", "authorization");
        return Result.getResult(UserInfoDto.class).setMessage("验证码登录成功").setCode(200).setData(user);
    }
    /**
     * 管理员接口
     * 启用用户状态
     * 参数
     * 令牌：authorization
     * 账号状态：state
     * 账号ID
     * */
    @GetMapping("/enableUserStateById.platform")
    @ApiOperation("/启用用户状态接口")
    @Permission(resources = "/enableUserStateById.platform")
    public Result enableStateById(@RequestHeader("authorization")String authorization,Integer userId) throws Exception {
        String refreshToken = redisUtil.get(authorization);
        Integer platformId = JwtUtil.getPlatformId(refreshToken);
        userAccountService.enableStateById(userId,platformId);
       return Result.getResult().setCode(200).setMessage("启用用户状态成功");
    }
    /**
     * 禁用用户状态
     * 参数
     * 令牌：authorization
     * 账号状态：state
     * */
    @GetMapping("/downUserStateById.platform")
    @ApiOperation("/禁用用户状态接口")
    @Permission(resources = "/downUserStateById.platform")
    public Result  downStateById(@RequestHeader("authorization")String authorization,Integer userId) throws Exception {
        System.out.println(authorization+"参数");
        String refreshToken = redisUtil.get(authorization);
        Integer platformId = JwtUtil.getPlatformId(refreshToken);
        userAccountService.downStateById(userId,platformId);
        return Result.getResult().setCode(200).setMessage("禁用用户状态成功");
    }
    /**
     * 删除用户
     * 参数
     * 令牌：authorization
     * 账号状态：state
     * */
    @GetMapping("/deleteUserStateById.platform")
    @Permission(resources = "/deleteUserStateById.platform")
    @ApiOperation("/删除用户接口")
    public Result  deleteStateById(@RequestHeader("authorization")String authorization,Integer userId) throws Exception {
        String refreshToken = redisUtil.get(authorization);
        Integer platformId = JwtUtil.getPlatformId(refreshToken);
        userAccountService.deleteStateById(userId,platformId);
        return Result.getResult().setCode(200).setMessage("删除用户成功");
    }
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /**  模块内调用方法
     * */

    /**
     * 根据ID查询用户账号
     * 参数: 用户Id userId
     * 返回: 用户Id userId
     *      用户账号 userAccount
     *      用户信息Id userInfoId
     * 方法: 1.判断userId是否存在对应的用户账号 若不存在则抛异常
     *      2.判断对应的用户帐号的状态是否是正常的 若不是则抛异常
     *      3.将用户账号放入Dto返回
     * */
    @GetMapping("/selectUserAccountById")
    @ApiOperation("根据ID查询用户账号")
    Result<UserAccountDto> selectUserAccountById(@RequestParam("userId") Integer userId) {
        UserAccount account = userAccountService.getById(userId);
        if (account==null) {
            throw new UserException(UserExceptionCode.USERINFO_IS_NOT);
        }
        if (account.getUserState()!= StateData.USER_STATE_ENABLE) {
            throw new UserException(UserExceptionCode.USER_ACCOUNT_STATE_ISNOT);
        }
        UserInfo user=userInfoService.getUserInfo(account.getUserId());
        UserAccountDto userAccountDto = BeanUtil.toBean(account, UserAccountDto.class);
        userAccountDto.setUserInfoId(user.getUserInfoId());
        return Result.getResult(UserAccountDto.class).setCode(200).setMessage("根据ID查询用户账号").setData(userAccountDto);
    }



}

